package com.duoqin.payservice.ui;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.duoqin.account.DuoqinAccount;
import com.duoqin.common.ui.AbsActivity;
import com.duoqin.common.viewmodel.BaseViewModel;
import com.duoqin.payservice.Pay;
import com.duoqin.payservice.data.ExpenseSummaryResponse;
import com.duoqin.payservice.data.HistoryResponse;
import com.duoqin.payservice.data.RechargeHistoryResponse;
import com.duoqin.payservice.viewmodel.PayViewModel;
import com.duoqin.syncassistant.R;

import java.util.ArrayList;
import java.util.List;

public class HistoryActivity extends AbsActivity {

    public static final String INTENT_EXTRA_HISOTRY_TYPE = "history_type";
    public static final String HISOTRY_TYPE_RECHARGE = "recharge";
    public static final String HISOTRY_TYPE_BILL = "bill";
    public static final String HISOTRY_TYPE_USE = "use";

    private final int DEFAULT_LIST_SIZE = 20;

    private class HistoryItem {
        RechargeHistoryResponse.DataBean rechargeHistoryData;
        HistoryResponse.DataBean.HistoriesBean historyData;
        ExpenseSummaryResponse.DataBean expenseSummaryData;

        HistoryItem() { }
    }

    private PayViewModel mPayViewModel;
    private List<HistoryItem> mHistoryItems = new ArrayList<>();
    private String mHistoryType;

    private ListView mListView;
    private View mProgressView;

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            showHistory();
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHistoryType = getIntent().getStringExtra(INTENT_EXTRA_HISOTRY_TYPE);
        if (TextUtils.isEmpty(mHistoryType)) {
            finish();
            return;
        }
        setContentView(R.layout.activity_history);
        if (HISOTRY_TYPE_RECHARGE.equals(mHistoryType)) {
            setupTitle(getString(R.string.recharge_history));
        } else if (HISOTRY_TYPE_BILL.equals(mHistoryType)) {
            setupTitle(getString(R.string.bill_history));
        } else {
            setupTitle(getString(R.string.history));
        }

        mListView = findViewById(R.id.log_list);
        mProgressView = findViewById(R.id.progress);

        setupModelObserver();
        getHistory();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }

    private void setupModelObserver() {
        mPayViewModel = ViewModelProviders.of(this).get(PayViewModel.class);
        final Observer<RechargeHistoryResponse> rechargeHistoryResponseObserver =
                new Observer<RechargeHistoryResponse>() {
            @Override
            public void onChanged(@Nullable RechargeHistoryResponse response) {
                Log.i(TAG, "onChanged RechargeHistoryResponse = " + response);
                if (response != null) {
                    Log.d(TAG, "onChanged code = " + response.getCode()
                            + "; msg = " + response.getMsg());
                    Log.d(TAG, "onChanged data = " + response.getData());
                    if (BaseViewModel.SERVER_RESULT_SUCCESS == response.getCode()) {
                        if (response.getData() != null) {
                            mHistoryItems.clear();
                            List<RechargeHistoryResponse.DataBean> rechargeHistoryDataList =
                                    response.getData();
                            for (RechargeHistoryResponse.DataBean historiesBean :
                                    rechargeHistoryDataList) {
                                HistoryItem historyItem = new HistoryItem();
                                historyItem.rechargeHistoryData = historiesBean;
                                mHistoryItems.add(historyItem);
                            }
                        }
                    }
                }
                mHandler.sendEmptyMessage(0); // Update UI
            }
        };
        mPayViewModel.rechargeHistoryResponseLiveData().observe(this,
                rechargeHistoryResponseObserver);

        final Observer<HistoryResponse> historyResponseObserver =
                new Observer<HistoryResponse>() {
                    @Override
                    public void onChanged(@Nullable HistoryResponse response) {
                        Log.i(TAG, "onChanged HistoryResponse = " + response);
                        if (response != null) {
                            Log.d(TAG, "onChanged code = " + response.getCode()
                                    + "; msg = " + response.getMsg());
                            Log.d(TAG, "onChanged data = " + response.getData());
                            if (BaseViewModel.SERVER_RESULT_SUCCESS == response.getCode()) {
                                if (response.getData() != null) {
                                    mHistoryItems.clear();
                                    List<HistoryResponse.DataBean.HistoriesBean> historiesBeanList =
                                            response.getData().getHistories();
                                    for (HistoryResponse.DataBean.HistoriesBean historiesBean :
                                            historiesBeanList) {
                                        HistoryItem historyItem = new HistoryItem();
                                        historyItem.historyData = historiesBean;
                                        mHistoryItems.add(historyItem);
                                    }
                                }
                            }
                        }
                        mHandler.sendEmptyMessage(0); // Update UI
                    }
                };
        mPayViewModel.historyResponseLiveData().observe(this, historyResponseObserver);

        final Observer<ExpenseSummaryResponse> expenseSummaryResponseObserver =
                new Observer<ExpenseSummaryResponse>() {
                    @Override
                    public void onChanged(@Nullable ExpenseSummaryResponse response) {
                        Log.i(TAG, "onChanged ExpenseSummaryResponse = " + response);
                        if (response != null) {
                            Log.d(TAG, "onChanged code = " + response.getCode()
                                    + "; msg = " + response.getMsg());
                            Log.d(TAG, "onChanged data = " + response.getData());
                            if (BaseViewModel.SERVER_RESULT_SUCCESS == response.getCode()) {
                                if (response.getData() != null) {
                                    mHistoryItems.clear();
                                    List<ExpenseSummaryResponse.DataBean> historiesBeanList =
                                            response.getData();
                                    for (ExpenseSummaryResponse.DataBean historiesBean :
                                            historiesBeanList) {
                                        HistoryItem historyItem = new HistoryItem();
                                        historyItem.expenseSummaryData = historiesBean;
                                        mHistoryItems.add(historyItem);
                                    }
                                }
                            }
                        }
                        mHandler.sendEmptyMessage(0); // Update UI
                    }
                };
        mPayViewModel.expenseSummaryResponseLiveData().observe(this,
                expenseSummaryResponseObserver);
    }

    private void getHistory() {
        showProgress(true, null);
        if (HISOTRY_TYPE_RECHARGE.equals(mHistoryType)) {
            mPayViewModel.getRechargeHistory(DuoqinAccount.getAccountToken(this));
        } else if (HISOTRY_TYPE_USE.equals(mHistoryType)) {
            mPayViewModel.getHistory(DuoqinAccount.getAccountToken(this), DEFAULT_LIST_SIZE);
        } else if (HISOTRY_TYPE_BILL.equals(mHistoryType)) {
            mPayViewModel.getExpenseSummary(DuoqinAccount.getAccountToken(this));
        }
    }

    private void showHistory() {
        if (mHistoryItems.size() > 0) {
            ListAdapter adapter = new ListAdapter();
            mListView.setAdapter(adapter);
            showProgress(false, mListView);
        } else {
            Toast.makeText(getApplicationContext(), R.string.history_not_found,
                    Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    private class Holder {
        TextView amountTV;
        TextView amount2TV;
        TextView noteTV;
        TextView timeTV;
    }

    private class ListAdapter extends BaseAdapter {
        private final Context mContext;
        private final LayoutInflater mInflater;

        ListAdapter() {
            mContext = getApplicationContext();
            mInflater = LayoutInflater.from(getApplicationContext());
        }

        @Override
        public int getCount() {
            return mHistoryItems.size();
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Holder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.list_item_history, parent, false);
                holder = new Holder();
                holder.amountTV = convertView.findViewById(R.id.amount);
                holder.amount2TV = convertView.findViewById(R.id.amount2);
                holder.noteTV = convertView.findViewById(R.id.note);
                holder.timeTV = convertView.findViewById(R.id.time);
                convertView.setTag(holder);
            } else {
                holder = (Holder) convertView.getTag();
            }

            HistoryItem historyItem = mHistoryItems.get(position);
            if (HISOTRY_TYPE_RECHARGE.equals(mHistoryType)) {
                if (historyItem.rechargeHistoryData != null) {
                    holder.amountTV.setText(mContext.getString(R.string.amount,
                            String.valueOf(historyItem.rechargeHistoryData.getRechargeBalance())));
                    holder.amount2TV.setVisibility(View.GONE);
                    if (historyItem.rechargeHistoryData.getRealFee() > 0) {
                        holder.noteTV.setText(mContext.getString(R.string.real_pay,
                                String.valueOf(historyItem.rechargeHistoryData.getRealFee())));
                        holder.noteTV.setVisibility(View.VISIBLE);
                    } else {
                        holder.noteTV.setVisibility(View.GONE);
                    }
                    holder.timeTV.setText(DateUtils.formatDateTime(mContext,
                            historyItem.rechargeHistoryData.getPayAt(),
                            DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
                }
            } else if (HISOTRY_TYPE_USE.equals(mHistoryType)) {
                if (historyItem.historyData != null) {
                    holder.amountTV.setText(mContext.getString(R.string.amount,
                            String.valueOf(historyItem.historyData.getBalanceChange())));
                    holder.amount2TV.setVisibility(View.GONE);
                    if (Pay.PRICE_UNIT_SEC.equalsIgnoreCase(historyItem.historyData.getUnit())) {
                        holder.noteTV.setText(mContext.getString(R.string.unit_sec,
                                String.valueOf(historyItem.historyData.getQuantity())));
                        holder.noteTV.setVisibility(View.VISIBLE);
                    } else if (Pay.PRICE_UNIT_CHARACTER.equalsIgnoreCase(
                            historyItem.historyData.getUnit())) {
                        holder.noteTV.setText(mContext.getString(R.string.unit_characters,
                                String.valueOf(historyItem.historyData.getQuantity())));
                        holder.noteTV.setVisibility(View.VISIBLE);
                    } else {
                        holder.noteTV.setVisibility(View.GONE);
                    }
                    holder.timeTV.setText(DateUtils.formatDateTime(mContext,
                            historyItem.historyData.getCreateAt(),
                            DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE
                                    | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NUMERIC_DATE));
                }
            } else if (HISOTRY_TYPE_BILL.equals(mHistoryType)) {
                if (historyItem.expenseSummaryData != null) {
                    holder.amountTV.setText(mContext.getString(R.string.voice_amount_quantity,
                            String.valueOf(historyItem.expenseSummaryData.getVoiceFee()),
                            historyItem.expenseSummaryData.getVoiceCount()));
                    holder.amount2TV.setText(mContext.getString(R.string.text_amount_quantity,
                            String.valueOf(historyItem.expenseSummaryData.getTextFee()),
                            historyItem.expenseSummaryData.getTextCount()));
                    holder.noteTV.setVisibility(View.GONE);
                    holder.timeTV.setText(historyItem.expenseSummaryData.getDate());
                }
            }
            return convertView;
        }
    }

    private void showProgress(final boolean show, final View focusView) {
        int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        mProgressView.animate().setDuration(shortAnimTime).alpha(
                show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
                mListView.setVisibility(!show ? View.VISIBLE : View.GONE);
                if (focusView != null) {
                    focusView.requestFocus();
                }
            }
        });
    }
}
